package com.axend.sofa.ui.activity

import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import cn.com.heaton.blelibrary.ble.callback.BleScanCallback
import cn.com.heaton.blelibrary.ble.model.BleDevice
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.axend.lib_base.base.activity.BaseVVDActivity
import com.axend.lib_base.bean.BleDeviceEntity
import com.axend.lib_base.engine.toast.toast
import com.axend.lib_base.ext.click
import com.axend.lib_base.ext.dp2px
import com.axend.lib_base.ext.expandTouchArea
import com.axend.lib_base.help.ble.BleClient
import com.axend.lib_base.livedatabus.LiveDatabus
import com.axend.lib_base.utils.ActivityManage
import com.axend.lib_base.utils.AnimationUtils
import com.axend.lib_base.utils.BluetoothScanUtil
import com.axend.lib_base.utils.log.MyLogUtils
import com.axend.lib_base.view.dialog.CustomTipsDialog
import com.axend.lib_service.ARouterPath
import com.axend.lib_service.Constant
import com.axend.sofa.BR
import com.axend.sofa.R
import com.axend.sofa.adapter.BleDeviceAdapter
import com.axend.sofa.databinding.ActivityBleConnectBinding
import com.axend.sofa.viewmodel.BleConnectViewModel
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.scwang.smart.refresh.header.MaterialHeader
import com.yxing.ScanCodeConfig
import com.yxing.def.ScanMode
import com.yxing.def.ScanStyle
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.annotation.Nullable
import javax.inject.Inject


/**
 * @author: cjs
 * @date: 2022/11/29
 * @desc:connect ble
 */
@AndroidEntryPoint
@Route(path = ARouterPath.ACTIVITY_MAIN_BLE)
class BleConnectActivity : BaseVVDActivity<BleConnectViewModel, ActivityBleConnectBinding>() {
    @Inject
    lateinit var bluetoothScanUtil: BluetoothScanUtil

    @Inject
    lateinit var devAdapter: BleDeviceAdapter

    var mExitTime: Long = 0

    /*tipsDialog*/
    private val tipsDialog by lazy {
        CustomTipsDialog.getInstance(
            this, getString(com.axend.lib_base.R.string.app_tips_disconnected),
            getString(com.axend.lib_base.R.string.app_tips_please_try_again)
        ) { p0, p1 ->
            p0.dismiss()
        }
    }


    override fun init(savedInstanceState: Bundle?) {
        // set viewModel
        mBinding.setVariable(BR.viewmodel, mViewModel)
        mBinding.executePendingBindings()

        // set adapter
        mBinding.rvList.apply {
            layoutManager = LinearLayoutManager(this@BleConnectActivity)
            adapter = devAdapter
            setHasFixedSize(true)
        }
        //set refresh ble scan
        mBinding.smartRefresh.setRefreshHeader(
            MaterialHeader(this).setColorSchemeColors(
                getColor(
                    com.axend.yxing.R.color.colorPrimary
                )
            )
        )
        //not set load
        mBinding.smartRefresh.setEnableLoadMore(false)

        initOnClick()
        initObserve()
    }


    private fun initOnClick() {
        mBinding.btOpenBle.click {
            /*跳转设置蓝牙开启*/
            startActivity(Intent(Settings.ACTION_BLUETOOTH_SETTINGS))
        }
        /*search*/
        mBinding.smartRefresh.setOnRefreshListener {
            beginScan()
        }

        devAdapter.setOnItemChildClickListener { adapter, view, position ->
            mViewModel.setSelectIndex(position)
        }

        /*扫描二维码*/
        mBinding.titleBar.rightLayout.expandTouchArea(60)
        mBinding.titleBar.rightLayout.click {
            XXPermissions.with(this@BleConnectActivity).permission(Permission.CAMERA)
                .permission(Permission.ACCESS_COARSE_LOCATION)
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
                        LiveDatabus.getInstance()
                            .withSticky(Constant.EVENT_BUS_KEY_SCAN_TITLE, String::class.java)
                            .postValue(getString(R.string.app_bar_title_scan_qr_code_sensor))
                        ScanCodeConfig.create(this@BleConnectActivity)
                            //设置扫码页样式 ScanStyle.NONE：无  ScanStyle.QQ ：仿QQ样式   ScanStyle.WECHAT ：仿微信样式  ScanStyle.CUSTOMIZE ： 自定义样式
                            .setStyle(ScanStyle.CUSTOMIZE)
                            //扫码成功是否播放音效  true ： 播放   false ： 不播放
                            .setPlayAudio(true)
                            //设置音效音频
//                .setAudioId(com.axend.sofa.R.raw.beep) ////////////////////////////////////////////
                            //以下配置 在style为 ScanStyle.CUSTOMIZE 时生效
                            //设置扫码框位置  left ： 边框左边位置   top ： 边框上边位置   right ： 边框右边位置   bottom ： 边框下边位置   单位/dp
                            //                                    .setScanRect(new ScanRect(50, 200, 300, 450), false)
                            //是否限制识别区域为设定扫码框大小  true:限制  false：不限制   默认false：识别区域为整个屏幕
                            .setLimitRect(true)
                            //设置扫码框位置 scanSize : 扫码框大小   offsetX ： x轴偏移量    offsetY ：y轴偏移量   单位 /px
                            .setScanSize(dp2px(300f), 0, 0)
                            //是否显示边框上四个角标 true ： 显示  false ： 不显示
                            .setShowFrame(true)
                            //设置边框上四个角标颜色
                            .setFrameColor(com.axend.lib_base.R.color.green_level_3)
                            //设置边框上四个角标圆角  单位 /dp
                            .setFrameRadius(2)
                            //设置边框上四个角宽度 单位 /dp
                            .setFrameWith(1)
                            //设置边框上四个角长度 单位 /dp
                            .setFrameLength(200)
                            //设置是否显示边框外部阴影 true ： 显示  false ： 不显示
                            .setShowShadow(true)
                            //设置边框外部阴影颜色
                            .setShadeColor(com.axend.lib_base.R.color.black_tran_level_1)
                            //设置扫码条运动方式   ScanMode.REVERSE : 往复运动   ScanMode.RESTART ：重复运动    默认ScanMode.RESTART
                            .setScanMode(ScanMode.REVERSE)
                            //设置扫码条扫一次时间  单位/ms  默认3000
                            .setScanDuration(3000) //设置扫码条图片
//                .setScanBitmapId(R.mipmap.scan_wechatline) //////////////////////////////////////////////
                            //以下配置在 setIdentifyMultiple 为 true 时生效
                            //设置是否开启识别多个二维码 true：开启 false：关闭   开启后识别到多个二维码会停留在扫码页 手动选择需要解析的二维码后返回结果
                            .setIdentifyMultiple(false)
                            //设置 二维码提示按钮的宽度 单位：px
                            .setQrCodeHintDrawableWidth(120)
                            //设置 二维码提示按钮的高度 单位：px
                            .setQrCodeHintDrawableHeight(120)
                            //设置 二维码提示按钮的Drawable资源
                            //.setQrCodeHintDrawableResource(R.mipmap.in)
                            //设置 二维码提示Drawable 是否开启缩放动画效果
                            .setStartCodeHintAnimation(true)
                            //设置 二维码选择页 背景透明度
                            .setQrCodeHintAlpha(0.5f)
                            .buidler()
                            //跳转扫码页   扫码页可自定义样式
                            .start(ScanQRCodeActivity::class.java)

                    }


                    override fun onDenied(
                        permissions: MutableList<String>,
                        doNotAskAgain: Boolean
                    ) {
                        if (doNotAskAgain) {
                            toast(getString(com.axend.lib_base.R.string.app_tips_permission_grant))
                            XXPermissions.startPermissionActivity(
                                this@BleConnectActivity,
                                permissions
                            )
                        } else {
                            toast(getString(com.axend.lib_base.R.string.app_tips_permission_fail))
                        }
                    }

                })

        }

        //双击退出
        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (System.currentTimeMillis() - mExitTime > 2000) {
                    toast(getString(com.axend.lib_base.R.string.app_tips_exit))
                    mExitTime = System.currentTimeMillis()
                    return
                } else {
                    ActivityManage.AppExit(this@BleConnectActivity)
                    return
                }
            }
        })

    }

    private fun initObserve() {
        mViewModel.devList.observe(this) {
            devAdapter.setList(it)
        }

        /*扫描观察*/
        mViewModel.isScanning.observe(this) {
            if (it) {
                /*将蓝牙权限申请到位*/
                XXPermissions.with(this).permission(bluetoothScanUtil.getPermissionArray())
                    .request(object : OnPermissionCallback {
                        override fun onGranted(
                            permissions: MutableList<String>,
                            allGranted: Boolean
                        ) {
                            if (!allGranted) {
                                return
                            }
                            /*开始搜寻动画*/
                            mBinding.ivBluetoothCircle.setImageResource(com.axend.lib_base.R.mipmap.img_bluetooth_background_light)
                            mBinding.ivBluetooth.setImageResource(com.axend.lib_base.R.mipmap.img_bluetooth_on)
                            AnimationUtils.start360Animation(
                                mBinding.ivBluetoothCircle
                            )
                            /*重新搜索 清空列表*/
//                            mViewModel.clearDevList()
                            BleClient.disconnectDevice()
                            startBleScan()
                        }

                        override fun onDenied(
                            permissions: MutableList<String>,
                            doNotAskAgain: Boolean
                        ) {
                            super.onDenied(permissions, doNotAskAgain)
                            if (doNotAskAgain) {
                                toast(getString(R.string.app_denied_permission))
                                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                                XXPermissions.startPermissionActivity(
                                    this@BleConnectActivity,
                                    permissions
                                )
                            } else {
                                toast(getString(R.string.app_permission_fail))
                            }
                        }

                    })
            } else {
                mBinding.ivBluetoothCircle.setImageResource(com.axend.lib_base.R.mipmap.img_bluetooth_background)
                mBinding.ivBluetooth.setImageResource(com.axend.lib_base.R.mipmap.img_bluetooth_off)
                AnimationUtils.end360Animation()
                BleClient.stopScan()
            }
        }


        /*选择索引*/
        mViewModel.selectIndex.observe(this) { it ->
            for (i in 0 until devAdapter.data.size) {
                devAdapter.data[i]?.let {
                    it.isSelect = false
                    it.connectLoading = false
                }
            }
            devAdapter.notifyDataSetChanged()

            if (devAdapter.data.size > 0) {
                var dataEntity = devAdapter.data[it]
                startConnect(dataEntity, null, it)
            }
        }
    }

    private fun beginScan() {
        if (mViewModel.blueToothEnable.value == false) return
        if (mViewModel.isScanning.value == true) return
        mViewModel.setIsScan(true)
    }


    /**
     * 开始扫描
     */
    private fun startBleScan() {
        /*开始扫描蓝牙获取结果*/
        BleClient.startScan(object : BleScanCallback<BleDevice>() {
            override fun onLeScan(
                device: BleDevice?,
                rssi: Int,
                scanRecord: ByteArray?
            ) {
                mViewModel.addDevice(BleDeviceEntity(bleDevice = device!!, rssi = rssi))
            }

            override fun onStart() {
                super.onStart()
                mBinding.smartRefresh.finishRefresh()
                mBinding.smartRefresh.setEnableRefresh(false)
            }

            override fun onStop() {
                super.onStop()
                mViewModel.setIsScan(false)
                mBinding.smartRefresh.setEnableRefresh(true)
            }

            override fun onScanFailed(errorCode: Int) {
                super.onScanFailed(errorCode)
                MyLogUtils.d("onScanFailed", "errorCode:$errorCode")
            }
        })
    }

    /**
     * 开始连接
     */
    private fun startConnect(dataEntity: BleDeviceEntity?, address: String?, index: Int?) {
        /*开始连接设备蓝牙*/
        (dataEntity?.bleDevice?.bleAddress ?: address)?.let { BleClient.connectDevice(it) }
        dataEntity?.apply {
            connectLoading = true
            isSelect = false
        }
        if (index != null && dataEntity != null) {
            devAdapter.setData(index, dataEntity)
        }
        BleClient.setDeviceConnectListener { bleDevice ->
            if (bleDevice.isConnecting) {
                dataEntity?.apply {
                    connectLoading = true
                    isSelect = false
                }
            } else if (bleDevice.isConnected) {
                dataEntity?.apply {
                    connectLoading = false
                    isSelect = true
                }
                /*连接后跳转设备页*/
                mViewModel.setIsScan(false)
                ARouter.getInstance().build(ARouterPath.ACTIVITY_MAIN_SENSOR)
                    .withTransition(
                        com.axend.lib_base.R.anim.base_slide_right_in,
                        com.axend.lib_base.R.anim.base_slide_right_out
                    )
                    .navigation(this)
            } else if (bleDevice.isDisconnected) {
                dataEntity?.apply {
                    connectLoading = false
                    isSelect = false
                }
                if (!tipsDialog.isShowing) {
                    tipsDialog.show()
                }
            }
            if (index != null && dataEntity != null) {
                devAdapter.setData(index, dataEntity)
            }
        }
    }

    private fun getDataEntityByName(name: String, callback: (BleDeviceEntity, Int) -> Unit) {
        for (entity in devAdapter.data) {
            if (entity.bleDevice.bleName == name) {
                callback(entity, devAdapter.data.indexOf(entity))
                return
            }
        }
    }

    override fun onResume() {
        super.onResume()
        /*蓝牙打开状态设置*/
        mViewModel.setBlueToothEnable(bluetoothScanUtil.isBluetoothAvailable())
        beginScan()
    }


    override fun onDestroy() {
        super.onDestroy()
        try {
            BleClient.stopScan()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK && data != null) {
            when (requestCode) {
                ScanCodeConfig.QUESTCODE -> {
                    //接收扫码结果
                    val extras = data.extras
                    if (extras != null) {
                        val codeType = extras.getInt(ScanCodeConfig.CODE_TYPE)
                        val code = extras.getString(ScanCodeConfig.CODE_KEY)
                        lifecycleScope.launch {
                            startConnect(null, code, null)
                        }
//                        getDataEntityByName(code!!) { bleDeviceEntity, position ->
//
//
//                        }

                    }
                }

//                ALBUM_QUEST_CODE -> {
//                    //接收图片识别结果
//                    val code = ScanCodeConfig.scanningImage(this, data.data)
//                    tvCode.setText(String.format("识别结果： %s", code))
//                }

                else -> {}
            }
        }
    }

}

